﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LotteryVote.Data;
using LotteryVote.Entity;
using LotteryVote.Logic.Exceptions;

namespace LotteryVote.Logic
{
    public class FreezeFundsFacade
    {
        private FreezeFundsDataAccess _daFreezeFunds;
        internal FreezeFundsDataAccess DaFreezeFunds
        {
            get
            {
                if (_daFreezeFunds == null)
                    _daFreezeFunds = new FreezeFundsDataAccess();
                return _daFreezeFunds;
            }
            set
            {
                _daFreezeFunds = value;
            }
        }

        private UserDataAccess _daUser;
        internal UserDataAccess DaUser
        {
            get
            {
                if (_daUser == null)
                    _daUser = new UserDataAccess();
                return _daUser;
            }
            set
            {
                _daUser = value;
            }
        }

        private UserInfoDataAccess _daUserInfo;
        internal UserInfoDataAccess DaUserInfo
        {
            get
            {
                if (_daUserInfo == null)
                    _daUserInfo = new UserInfoDataAccess();
                return _daUserInfo;
            }
            set
            {
                _daUserInfo = value;
            }
        }

        /// <summary>
        /// 冻结用户资金.
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <param name="amount">The amount.</param>
        public void FreezeUserFunds(int userId, decimal amount)
        {
            var userInfo = DaUserInfo.GetUserInfo(userId);
            if (userInfo.AvailableGivenCredit < amount)
                throw new InvalidGivenCreditException(userInfo.AvailableGivenCredit, amount);
            userInfo.AvailableGivenCredit -= amount;
            DaFreezeFunds.ExecuteWithTransaction(() =>
            {
                DaUserInfo.Tandem(DaFreezeFunds);
                DaUserInfo.Update(userInfo);
                AddFreezeFunds(userId, amount);
            });
        }
        public void UnFreezeUserFunds(int userId, decimal amount)
        {
            var userInfo = DaUserInfo.GetUserInfo(userId);
            userInfo.AvailableGivenCredit += amount;
            DaFreezeFunds.ExecuteWithTransaction(() =>
            {
                DaUserInfo.Tandem(DaFreezeFunds);
                DaUserInfo.Update(userInfo);
                UnFreezeFunds(userId, amount);
            });
        }
        public void AddFreezeFunds(int userId, decimal amount)
        {
            var freezeFund = DaFreezeFunds.GetFreezeFundsByUser(userId, BetStatus.Valid);
            if (freezeFund != null)
            {
                freezeFund.Amount += amount;
                DaFreezeFunds.UpdateFreeze(freezeFund);
            }
            else
            {
                freezeFund = new FreezeFunds
                {
                    UserId = userId,
                    Amount = amount,
                    Status = BetStatus.Valid
                };
                DaFreezeFunds.InsertFreeze(freezeFund);
            }
        }
        /// <summary>
        ///解冻资金.
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <param name="amount">The amount.</param>
        public void UnFreezeFunds(int userId, decimal amount)
        {
            var freezeFund = DaFreezeFunds.GetFreezeFundsByUser(userId, BetStatus.Valid);
            if (freezeFund == null)
                throw new InvalidDataException("user have not valid freeze funds,userId:" + userId);
            freezeFund.Amount -= amount;
            DaFreezeFunds.UpdateFreeze(freezeFund);
        }
        public void UnFreezeOrder(BetOrder order)
        {
            UnFreezeUserFunds(order.UserId, order.Turnover);
        }

        public void ClearFreezeFunds(int userId)
        {
            var freezeFund = DaFreezeFunds.GetFreezeFundsByUser(userId, BetStatus.Valid);
            if (freezeFund == null)
                return;
            var userInfo = DaUserInfo.GetUserInfo(userId);
            if (userInfo == null)
                throw new InvalidDataException("userInfo,UserId:" + userId);
            DaFreezeFunds.ExecuteWithTransaction(() =>
            {
                decimal amount = freezeFund.Amount;
                freezeFund.Amount = 0;
                DaFreezeFunds.UpdateFreeze(freezeFund);

                DaUserInfo.Tandem(DaFreezeFunds);
                userInfo.AvailableGivenCredit += amount;
                DaUserInfo.Update(userInfo);
            });
        }

        public FreezeFunds GetFreezeFund(int userId)
        {
            return DaFreezeFunds.GetFreezeFundsByUser(userId, BetStatus.Valid);
        }
    }
}
